package org.budo.mybatis.dao.factory;

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.budo.mybatis.dao.MybatisDao;
import org.budo.mybatis.dao.impl.MybatisDaoImpl;
import org.budo.support.lang.util.ReflectUtil;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.beans.factory.FactoryBean;

import lombok.Getter;
import lombok.Setter;

/**
 * @author limingwei
 */
@Getter
@Setter
public class MybatisDaoFactory implements FactoryBean<MybatisDao> {
    private static final Logger log = Slf4j.getLogger();

    private MybatisDaoImpl _mybatisDao = null;

    private SqlSessionFactory sqlSessionFactory;

    private DataSource dataSource;

    private Interceptor[] plugins;

    // com.github.pagehelper.PageInterceptor
    public void setPluginType(Class<?> pluginType) {
        Interceptor interceptor = (Interceptor) ReflectUtil.newInstance(pluginType);
        interceptor.setProperties(new Properties());
        this.setPlugins(new Interceptor[] { interceptor });
    }

    public MybatisDao getObject() throws Exception {
        if (null != this._mybatisDao) {
            return this._mybatisDao;
        }

        synchronized (MybatisDaoFactory.class) {
            if (null != this._mybatisDao) {
                return this._mybatisDao;
            }

            return this._mybatisDao = this.initMybatisDao();
        }
    }

    private MybatisDaoImpl initMybatisDao() {
        MybatisDaoImpl mybatisDao = new MybatisDaoImpl();
        mybatisDao.setSqlSessionFactory(this.getSqlSessionFactory());
        mybatisDao.setDataSource(this.getDataSource());
        mybatisDao.setPlugins(this.getPlugins());

        log.info("#42 initMybatisDao, mybatisDao=" + mybatisDao + ", sqlSessionFactory=" + this.getSqlSessionFactory() + ", dataSource=" + this.getDataSource());
        return mybatisDao;
    }

    public Class<?> getObjectType() {
        return MybatisDao.class;
    }

    public boolean isSingleton() {
        return true;
    }
}